home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World Interactive 1
/
PC World Interactive 1 - Nisan 1997.iso
/
nostalji
/
bbs
/
modem
/
telix.arj
/
QDHOST.SLT
< prev
next >
Wrap
Text File
|
1993-02-05
|
29KB
|
1,100 lines
//////////////////////////////////////////////////////////////////////////////
//
// Q D H O S T . S L T
//
// Copyright (C) 1988-1992 deltaComm Development.
//
// - Written by Colin Sampaleanu.
// - Modifications by Jeff Woods, Feb '91, to add help function and support
// for locked modems.
// - Modifications by Dan Horn, Nov '92, fixed 'floating' timer bug.
//
//
// This is a Host Mode for Telix, written as a script file.
// To configure Host Mode parameters such as passwords, run the 'QDCONFIG'
// script. That script is run automatically if the Host Mode configuration
// file 'QDHOST.CNF' is missing.
//
// This script will only work with Hayes compatible modems, but may be
// modified for operation with other modems.
//
//////////////////////////////////////////////////////////////////////////////
// Parameters which can be configured
str pass1[8] = "pass1", // The level 1 pass
pass2[8] = "pass2", // The level 2 (Sysop) pass
shellpass[8] = "shell", // the pass to enter the Remote Shell
shutpass[8] = "shut", // the pass to shut down the Host Mode
host_downloads[64], // where users may download from
host_uploads[64]; // where uploaded files go
int direct_connect = 0,
modem_lock = 0;
str current_caller[31], // storage of current caller's name
conn300[] = "CONNECT^M", // modem result messages for bauds
conn1200[] = "CONNECT 1200",
conn2400[] = "CONNECT 2400",
conn9600[] = "CONNECT 9600",
conn19200[] = "CONNECT 19200";
int finished_caller, // set to TRUE when must return to top
local_mode, // set to TRUE when local test mode
access_level, // access level of current caller
carrier_counts = 1, // TRUE if should watch Carrier signal
already_connected = 0,
exit_requested = 0, // set to TRUE if Sysop has pressed Esc
connection_lost = 0, // set to TRUE when carrier lost
kill_user = 0; // set to TRUE when user must be purged
int old_scr_chk_key, // storage for some system variables
old_cisb_auto, // which we have to modify and put
old_zmod_auto, // back to what they were when done
old_sound;
str old_down_dir[64],
old_up_dir[64],
old_usage_fname[64];
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
main()
{
int c;
clear_scr();
if (read_host_config_file() == -1)
{
prints("Unable to read QDHOST.CNF...");
prints("Running QDCONFIG, the Host Mode configuration script.^M^J");
call("QDCONFIG");
if (read_host_config_file() == -1)
{
prints("Still unable to read QDHOST.CNF. Aborting Host Mode.^M^J");
return -1;
}
}
if (!check_directories())
{
prints("Either the upload or download directory as defined in the QDHOST.CNF file");
prints("doesn't exist. Either create the missing directory with the DOS 'MKDIR'");
prints("command, or run the QDCONFIG script to redefine what directories to use.");
prints("Aborting Host Mode.");
return -1;
}
old_scr_chk_key = _scr_chk_key;
_scr_chk_key = 0;
old_cisb_auto = _cisb_auto;
_cisb_auto = 0;
old_zmod_auto = _zmod_auto;
_zmod_auto = 0;
old_sound = _sound_on;
_sound_on = 0;
old_down_dir = _down_dir;
_down_dir = host_uploads; // these are reversed because we are now the Host
old_up_dir = _up_dir;
_up_dir = host_downloads; // these are reversed because we are now the Host
old_usage_fname = _usage_fname;
usagelog("QDHOST.LOG");
if (direct_connect)
carrier_counts = 0;
else
carrier_counts = 1;
if (!direct_connect && carrier())
already_connected = 1;
while (1)
{
if (!direct_connect && !already_connected)
{
if (!modem_lock)
set_cparams(modem_lock, 0, 8, 1);
delay(3);
prints("Sending Modem Init string...");
cputs_tr(_mdm_init_str);
delay(10);
prints("Sending Auto-Answer string...");
cputs_tr(_auto_ans_str);
}
finished_caller = kill_user = 0;
if (direct_connect)
carrier_counts = 0;
else
carrier_counts = 1;
if (!direct_connect)
{
prints("^M^JQDHost Mode: Waiting for call...");
prints("(Press Esc to exit, or 'L' for local test mode).^M^J");
do
{
if (carrier())
{
local_mode = 0;
break;
}
c = inkey();
if (c)
{
if (c == 27)
{
exit_requested = 1;
break;
}
else if (c == 'l' || c == 'L') // local teswt mode
{
prints("Local test mode entered");
local_mode = 1;
carrier_counts = 0;
}
}
}
while (toupper(c) != 'L');
}
if (!exit_requested)
{
prints("Incoming call. Sysop: press Esc to exit, or END to terminate user.");
do_one_caller();
if ((connection_lost || kill_user) && carrier_counts && carrier())
hangup(); // make sure nobody sneaks in
}
already_connected = 0;
if (exit_requested)
{
if (!carrier() && !direct_connect)
{
prints("Sending Modem Init string...");
cputs_tr(_mdm_init_str);
}
_scr_chk_key = old_scr_chk_key;
_cisb_auto = old_cisb_auto;
_zmod_auto = old_zmod_auto;
_sound_on = old_sound;
_down_dir = old_down_dir;
_up_dir = old_up_dir;
prints("^M^JQDHost mode script finished.");
usagelog("*CLOSE*");
_usage_fname = old_usage_fname;
return 1;
}
}
}
//////////////////////////////////////////////////////////////////////////////
HelpOn(int option)
{
if (option == 'H')
{
host_send("^M^JHelp on Help^M^J");
host_send("^M^JTo use the help, simply type the first letter of one of the following:");
host_send("^M^J^M^J<H>elp <F>iles <T>ype <U>pload <D>ownload <S>hell <C>hat <G>oodbye");
Host_send("^M^J");
}
if (option == 'F')
{
host_send("^M^JHelp on Files^M^J");
host_send("^M^JThe 'Files' option allows the caller to list the files in the");
host_send("^M^Jcurrent disk directory. The caller must press a key after each");
host_send("^M^Jscreen. The output is not echoed on the local screen. If the");
host_send("^M^Jcaller has access level two s/he is prompted for a filespec,");
host_send("^M^Jwhich may include the * and ? wildcard characters (see your");
host_send("^M^JDOS manual), so that the contents of other directories than");
host_send("^M^Jthe 'Host download dir' may be listed.");
Host_send("^M^J");
}
if (option == 'T')
{
host_send("^M^JHelp on Type^M^J");
host_send("^M^JThe 'Type' option allows the caller to view any ASCII file in");
host_send("^M^Jthe Host Download Directory, or in any directory for access");
host_send("^M^JLevel 2 callers. Simply give the name (or full path and name)");
host_send("^M^Jof the system file you wish to view: ie. C:\TELIX\TELIX.IMG");
Host_send("^M^J");
}
if (option == 'U')
{
host_send("^M^JHelp on Uploading^M^J");
host_send("^M^JThe 'Upload' option allows the caller to send a file to the");
host_send("^M^Jhost. The caller is shown the a menu of protocols. He/she");
host_send("^M^Jshould select the appropriate protocol by its first letter");
host_send("^M^J(or 'E' for Ymodem-g). If appropriate the caller is also asked");
host_send("^M^Jfor the filename. The transfer is then initiated by QDHOST. The");
host_send("^M^Jcaller must then initiate the upload on THEIR side by giving");
host_send("^M^Jtheir comm program an upload instruction, choosing the same");
host_send("^M^Jprotocol as they told host, and giving the filename again,");
host_send("^M^Jwithin 60 seconds of telling QDHOST the same information.");
Host_send("^M^J");
}
if (option == 'D')
{
host_send("^M^JHelp on Downloading^M^J");
host_send("^M^JThe 'Download' command allows a caller to receive a file from");
host_send("^M^Jthe host. The caller must select the protocol after giving the");
host_send("^M^Jdownload command to QDHOST, and then must tell QDHOST what files");
host_send("^M^Jto send. Some protocols like ZModem will start automatically");
host_send("^M^Jafter this. Others, like XModem, require the caller to start");
host_send("^M^Ja download in their comm program at this point (usually Pg-Dn)");
host_send("^M^Jand will be asked by the comm program for a file name again. The");
host_send("^M^Jtransfer is then initiated.");
Host_send("^M^J");
}
if (option == 'S')
{
host_send("^M^JHelp on Shelling^M^J");
host_send("^M^JThe 'Shell' command is a very powerful but also very dangerous");
host_send("^M^Jcommand. It allows the caller to run a DOS shell on the sys-");
host_send("^M^Jtem, except that the caller receives the output, and the");
host_send("^M^Jcaller enters the keystrokes. The caller has complete control");
host_send("^M^Jof the HOST system at the DOS level. Shell is a password");
host_send("^M^Jprotected feature of QDHOST. The caller sees program output only");
host_send("^M^Jif the programs use standard DOS output. Programs that write");
host_send("^M^Jdirectly to the video screen will work, but will not be seen");
host_send("^M^Jby the remote caller. As well, programs that use non-DOS meth-");
host_send("^M^Jods of getting keystrokes will not receive the callers");
host_send("^M^Jkeystrokes. Finally, under some systems, if the caller presses");
host_send("^M^JBackspace at the DOS prompt when the current line is empty,");
host_send("^M^JDOS will hang on the Host machine. As these are functions of");
host_send("^M^JDOS, there is nothing that can be done about these limits.");
Host_send("^M^J");
}
if (option == 'C')
{
host_send("^M^JHelp on Chatting^M^J");
host_send("^M^JThe 'Chat' command allows the caller to chat with the host op-");
host_send("^M^Jerator. When the caller presses 'C' the host operator is paged");
host_send("^M^Jfor 20 seconds. If the host operator responds, you will see");
host_send("^M^Jhim/her typing on your screen. If you can, place yourself in");
host_send("^M^JChat Mode, by using your comm program's chat mode (Telix's is");
host_send("^M^JAlt-Y). You will then see what you type on half of the screen");
host_send("^M^Jand the operator's words on the other half.");
Host_send("^M^J");
}
if (option == 'G')
{
host_send("^M^JHelp on Goodbye^M^J");
host_send("^M^JThe 'Goodbye' command allows the caller to log off the host");
Host_send("^M^J");
}
}
//////////////////////////////////////////////////////////////////////////////
do_one_caller()
{
str strn[80],
fname[64];
int option,
status,
c, i, i2, f;
access_level = 1;
if (already_connected)
prints("Already connected, or modem Carrier Detect switch improperly set!");
else if (carrier_counts)
{
if (!modem_lock)
if (!determine_baud())
; // do something else here if this is a problem
}
delay(10);
type_file("LOGO.MSG");
flushbuf();
while (1)
{
host_send("Please enter your full name: ");
host_input_strn(current_caller, 30, 1);
host_send("^M^J");
if (finished_caller)
return;
if (strlen(current_caller) >= 5)
break;
}
access_level = ask_for_pass(3, pass1, pass2);
if (access_level)
ustamp("Logon by ", 1, 0);
else
ustamp("Failed logon attempt by ", 1, 0);
ustamp(current_caller, 0, 1);
if (!access_level)
{
host_send("Goodbye!^M^J");
if (carrier_counts)
{
delay(10);
hangup();
}
return;
}
type_file("WELCOME.MSG");
while (1)
{
if (finished_caller)
return;
host_send("^M^JCommand: Help Files Type Upload Download Shell Chat Goodbye ? ");
host_input_strn(strn, 1, 1);
option = toupper(subchr(strn, 0));
host_send("^M^J");
if (option == 'H')
{
host_send("^M^J^M^JWhich item above do you wish help on? ");
host_input_strn(strn, 1, 1);
Option = toupper(subchr(strn, 0));
Host_send("^M^J");
HelpOn(Option);
Option = 'H';
}
if (option == 'F') // Files directory
{
if (access_level == 2)
{
host_send("Enter 'filespec' or press Return for *.*,^M^J: ");
host_input_strn(fname, 64, 1);
host_send("^M^J");
if (just_filename(fname))
{
strn = host_downloads;
strcat(strn, fname);
}
else
strn = fname;
}
else
{
strn = host_downloads;
strcat(strn, "*.*");
}
if (local_mode)
show_directory(strn, 0, carrier_counts);
else
show_directory(strn, 1, carrier_counts);
host_send("^M^J");
}
else if (option == 'T') // Type a file
{
host_send("Type what file? ");
host_input_strn(strn, 64, 1);
host_send("^M^J");
if (access_level != 2) // if access 1, name and ext only
fnstrip(strn, 3, fname);
else
fname = strn;
if (just_filename(fname))
{
strn = host_downloads;
strcat(strn, fname);
fname = strn;
}
if (!filefind(fname, 0, strn))
{
host_send("Unable to find ");
host_send(fname);
continue;
}
type_file(fname);
}
else if (option == 'G') // Goodbye (Hang-up)
{
host_send("^M^JGoodbye!^M^J");
ustamp("User logged off.", 1, 1);
if (carrier_counts)
{
delay(10);
hangup();
}
return;
}
else if (option == 'C') // Chat mode
{
prints("Sysop: Press Space to chat, any other key not to.^M^J");
c = 0;
_sound_on = 1;
for (i = 8; i && !c; --i)
{
if (carrier_counts && !carrier())
{
prints("^M^JConnection has been lost, call terminated.^M^J");
connection_lost = 1;
finished_caller = 1;
break;
}
cputc('^G');
tone(523, 20);
tone(659, 20);
tone(523, 20);
tone(659, 20);
tone(523, 20);
tone(659, 20);
for (i2 = 30; i2 && (c = inkey()) == 0; --i2)
delay(1);
}
_sound_on = 0;
if (finished_caller)
continue;
if (c != ' ' || !c)
{
host_send("Sorry, the Sysop is unavailable^M^J");
continue;
}
host_send("The sysop is here!^M^J");
chatmode(1);
}
else if (option == 'U') // User upload
{
option = host_get_prot();
if (!option)
continue;
status = 1;
if (option == 'T' || option == 'M' || option == 'S' ||
option == 'Y' || option == 'Z' || option == 'E')
{
send_transfer_msg();
status = receive(option, "");
}
else
{
host_send("Upload what file? ");
host_input_strn(strn, 48, 1);
host_send("^M^J");
if (!strn)
continue;
if (access_level != 2) // if access 1, name and ext only
fnstrip(strn, 3, fname);
else
fname = strn;
if (just_filename(fname))
{
strn = host_uploads;
strcat(strn, fname);
fname = strn;
}
if (filefind(fname, 23, strn))
host_send("File already exists!^M^J");
else
{
send_transfer_msg();
status = receive(option, fname);
}
}
if (status == -2) // Carrier lost
connection_lost = finished_caller = 1;
else if (status == -1)
host_send("^GOne or more files not received!^M^J");
}
else if (option == 'D') // User download
{
option = host_get_prot();
if (!option)
continue;
host_send("Download what file(s)? ");
host_input_strn(strn, 48, 1);
host_send("^M^J");
if (!strn)
continue;
if (access_level != 2) // if not level 2, keep only name & ext
fnstrip(strn, 3, fname);
else
fname = strn;
if (just_filename(fname))
{
strn = host_downloads;
strcat(strn, fname);
fname = strn;
}
if (!filefind(fname, 0, strn))
{
host_send("Unable to find any matching file(s)!^M^J");
continue;
}
status = 1;
send_transfer_msg();
status = send(option, fname);
if (status == -2) // Carrier lost
connection_lost = finished_caller = 1;
else if (status == -1)
host_send("^GOne or more files not received!^M^J");
}
else if (option == 'S') // Remote shell
{
if (ask_for_pass(3, shellpass, shellpass) != 0)
{
host_send("Type EXIT and then press Enter to come back.^M^J");
if (get_baud() == 300)
delay(10);
if (local_mode)
dos("", 0);
// See if user has prepared a custom file for shell operation
// and call that if it exists
else if (filefind("RSHELL.BAT", 0, strn))
dos("RSHELL.BAT", 0);
else // otherwise make our own temporary batch file for redirection
{
// now want to make a temporary batch file which will be called
// to redirect DOS input and output, then shell to another copy
// of COMMAND.COM
f = fopen("HOSTTEMP.BAT", "w");
if (f)
{
if (get_port() != 1 && get_port() != 2)
{
host_send("Remote Shell not supported on this comm port due to DOS limits!^M^J");
continue;
}
strn = "COMx";
setchr(strn, 3, get_port() + '0'); // get right name to redirect
fputs("CTTY ", f); // write to batch file
fputs(strn, f);
fputs("^M^JCOMMAND^M^J", f);
fputs("CTTY CON^M^J", f);
fputs("EXIT^M^J", f);
fclose(f); // close the file
if (!local_mode) // call batch file
dos("HOSTTEMP.BAT", 0);
}
else
host_send("Can't open temporary batch file!^M^J");
}
}
}
else if (option == '^Z') // Shut down Host Mode
{
host_send("Shut down QDHost mode. ");
if (!ask_for_pass(3, shutpass, shutpass))
continue;
host_send("Goodbye!^M^J");
if (carrier_counts)
hangup();
ustamp("User shut down QDHost Mode.", 1, 1);
finished_caller = 1;
exit_requested = 1;
}
}
}
//////////////////////////////////////////////////////////////////////////////
host_get_prot()
{
str prot[1];
host_send("^M^JModem7 SEAlink Xmodem 1k-Xmodem G-1k-Xmodem Ymodem YmodEm-g Zmodem^M^J");
host_send("Which protocol? ");
host_input_strn(prot, 1, 1);
host_send("^M^J");
if (strposi("MSX1GYEZ", prot, 0) == -1) // if illegal prot
prot = ""; // return 0
return (toupper(subchr(prot, 0)));
}
//////////////////////////////////////////////////////////////////////////////
send_transfer_msg()
{
host_send("Ready to transfer file(s)... Press Ctrl-X at least twice to abort^M^J");
}
//////////////////////////////////////////////////////////////////////////////
// Determine the baud rate once a Carrier Detect Signal has been detected
// Since no characters were read, the 'CONNECT' string should still be
// in the receive buffer.
determine_baud()
{
int t3, t12, t24, t96, t192;
int tmark, stat;
int new_baud = 0;
printsc("Determining baud... ");
track_free(0); // clear all existing tracks
t3 = track(conn300, 0); // check for connect strings
t12 = track(conn1200, 0);
t24 = track(conn2400, 0);
t96 = track(conn9600, 0);
t192 = track(conn19200, 0);
tmark = timer_start(30); // wait up to 3 seconds for string
while (!time_up(tmark))
{
if (!carrier())
{
track_free(0); // clear all existing tracks
timer_free(tmark); // free existing timer
return 0;
}
if (cinp_cnt())
track_addchr(cgetc());
stat = track_hit(0);
if (stat == 0)
continue;
if (stat == t3)
new_baud = 300;
else if (stat == t24)
new_baud = 2400;
else if (stat == t96)
new_baud = 9600;
else if (stat == t192)
new_baud = 19200;
else
new_baud = 1200;
break; // have baud rate, get out
}
track_free(0); // clear all existing tracks
timer_free(tmark); // free existing timer
if (!new_baud) // time-up without CONNECT string
{
prints("Failed!");
return 0;
}
printn(new_baud);
prints("");
set_cparams(new_baud, get_parity(), get_datab(), get_stopb());
return 1; // indicate success
}
//////////////////////////////////////////////////////////////////////////////
type_file(str fname)
{
int f;
str buf[100];
int ichar, lines_sent = 0;
f = fopen(fname, "r");
if (!f)
return -1;
host_send("^M^J");
while (1)
{
if (carrier_counts)
if (!carrier())
{
connection_lost = 1;
finished_caller = 1;
fclose(f);
return 0;
}
if (fgets(buf, 80, f) == -1)
{
fclose(f);
return 1;
}
host_send(buf);
host_send("^M^J");
++lines_sent;
if (lines_sent >= 22)
{
lines_sent = 0;
host_send("[More]");
host_input(1);
if (finished_caller) // if user inactivity
{
fclose(f);
return 0;
}
host_send("^H ^H^H ^H^H ^H^H ^H^H ^H^H ^H^H ^H");
}
while (cinp_cnt())
{
ichar = cgetc();
if (ichar == '^C' || ichar == '^K')
{
host_send("^M^J");
fclose(f);
return 1;
}
}
}
}
//////////////////////////////////////////////////////////////////////////////
host_send(str outstr)
{
printsc(outstr);
if (!local_mode)
cputs(outstr);
}
//////////////////////////////////////////////////////////////////////////////
host_send_c(int chr)
{
printc(chr);
if (!local_mode)
cputc(chr);
}
//////////////////////////////////////////////////////////////////////////////
host_input_strn(str buf, int maximum, int echoable)
{
int i = 0, key;
while (1)
{
key = host_input(echoable);
if (!key) // timeout or user disconnect
{
setchr(buf, 0, 0); // set string to empty
return 0; // indicate there is a problem
}
if (key == '^M')
break;
if (key == 127 || key == 8)
{
if (i)
{
--i;
host_send_c(key);
}
continue;
}
if (i < maximum)
{
setchr(buf, i, key);
i = i + 1;
}
else
i = i + 1;
}
if (i > maximum)
i = maximum;
setchr(buf, i, '^0');
if (subchr(buf, 0))
return 1;
else
return 0;
}
//////////////////////////////////////////////////////////////////////////////
host_input(int echoable)
{
int c;
int t;
t = timer_start(2400); // 4 minutes inactivity allowed
while (1)
{
if (time_up(t) && !direct_connect)
{
host_send("^M^J^M^JInactivity period too long. Connection terminated!^M^J");
if (carrier_counts)
hangup();
finished_caller = 1;
kill_user = 1;
break;
}
if (carrier_counts)
if (!carrier())
{
prints("^M^JConnection has been lost, call terminated.^M^J");
connection_lost = 1;
finished_caller = 1;
break;
}
if ((c = inkey()) != 0)
{
if (c == 27) // ESC key, sysop wants to exit
{
finished_caller = 1;
exit_requested = 1;
break;
}
else if (c == 0x4f00) // END key, temrinate user
{
prints("^M^JUser terminated!");
ustamp("User terminated!", 1, 1);
if (carrier_counts)
hangup();
finished_caller = 1;
kill_user = 1;
break;
}
else if (c <= 255)
{
if (c != 8 && c != 127)
if (!echoable)
host_send_c('*');
else
host_send_c(c);
break;
}
}
if (!local_mode)
if (cinp_cnt())
{
c = cgetc();
if (c != 8 && c != 127)
if (!echoable)
host_send_c('*');
else
host_send_c(c);
break;
}
}
timer_free(t); // free existing timer
if (finished_caller)
return 0; // return 0 - no character
return c; // return received/pressed character
}
//////////////////////////////////////////////////////////////////////////////
ask_for_pass(int maxtries, str pass1, str pass2)
{
int i;
str strn[8];
for (i = 0; i < maxtries; ++i)
{
if (i)
host_send("Wrong! Try again.^M^J");
host_send("Password: ");
host_input_strn(strn, 8, 0);
host_send("^M^J");
if (finished_caller)
return 0;
if (!strcmpi(strn, pass1))
return 1;
if (!strcmpi(strn, pass2))
return 2;
}
host_send("No more chances. Access denied.^M^J");
return 0;
}
//////////////////////////////////////////////////////////////////////////////
read_host_config_file()
{
str s[80];
int f, stat;
s = _telix_dir;
strcat(s, "QDHOST.CNF");
f = fopen(s, "r");
if (!f)
{
printsc("Can't open ");
prints(s);
return -1;
}
stat = fgets(s, 80, f);
if (stat == -1)
goto got_error;
pass1 = s;
stat = fgets(s, 80, f);
if (stat == -1)
goto got_error;
pass2 = s;
stat = fgets(s, 80, f);
if (stat == -1)
goto got_error;
shellpass = s;
stat = fgets(s, 80, f);
if (stat == -1)
goto got_error;
shutpass = s;
stat = fgets(s, 80, f);
if (stat == -1)
goto got_error;
host_downloads = s;
stat = fgets(s, 80, f);
if (stat == -1)
goto got_error;
host_uploads = s;
stat = fgets(s, 80, f);
if (stat == -1)
goto got_error;
direct_connect = (toupper(subchr(s, 0)) == 'D');
stat = fgets(s, 80, f);
if (stat == -1)
goto got_error;
modem_lock = stoi(s);
fclose(f);
return 1;
// jump here if error
got_error:
fclose(f);
return -1;
}
//////////////////////////////////////////////////////////////////////////////
check_directories()
{
str s[80];
int i, a;
// first remove trailing slashes
s = host_uploads;
i = strlen(s);
if (i > 0)
if (subchr(s, i - 1) == '\' || subchr(s, i - 1) == '/')
setchr(s, i - 1, 0);
if (s && !(strlen(s) == 2 && subchr(s, 1) == ':'))
{
a = fileattr(s);
if (a == -1 || !(a & 16))
return 0; // not a directory or doesn't exist
}
s = host_downloads;
i = strlen(s);
if (i > 0)
if (subchr(s, i - 1) == '\' || subchr(s, i - 1) == '/')
setchr(s, i - 1, 0);
if (s && !(strlen(s) == 2 && subchr(s, 1) == ':'))
{
a = fileattr(s);
if (a == -1 || !(a & 16))
return 0; // not a directory or doesn't exist
}
return 1;
}
//////////////////////////////////////////////////////////////////////////////
// returns TRUE if passed filespec is just a filename. Also handles the
// forward slash as a path separator.
just_filename(str filespec)
{
int slash, space;
if (strpos(filespec, ":", 0) != -1)
return 0;
if (strpos(filespec, "\", 0) != -1)
return 0;
if ((slash = strpos(filespec, "/")) == -1)
return 1;
space = strpos(filespec, " ");
if (space == -1)
return 0;
if (space < slash)
return 1;
return 0;
}
//////////////////////////////////////////////////////////////////////////////